package net.thxjj.adminServer.mongodao;

import net.thxjj.adminServer.entity.StaticBean;
import net.thxjj.adminServer.entity.aep.HeartData;
import net.thxjj.adminServer.util.DataUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Objects;

@Component
public class MongoHeartDao {

    @Autowired
    private MongoTemplate mongoTemplate;

    //导入所有数据
    public void saveAllData(List<HeartData> list){
        mongoTemplate.insert(list,HeartData.class);
    }

    private void updateHeartData(HeartData heartData) {
        Query query = new Query(Criteria.where("deviceId").is(heartData.getDeviceId()).and("timestamp").is(heartData.getTimestamp()));
        Update update = new Update()
                .set("terminal_type",heartData.getTerminal_type())
                .set("software_version",heartData.getSoftware_version())
                .set("sinr",heartData.getSinr())
                .set("rsrp",heartData.getRsrp())
                .set("pci",heartData.getPci())
                .set("manufacturer_name",heartData.getManufacturer_name())
                .set("heartbeat_time",heartData.getHeartbeat_time())
                .set("hardware_version",heartData.getHardware_version())
                .set("ecl",heartData.getEcl())
                .set("cell_ID",heartData.getCell_ID())
                .set("battery_voltage",heartData.getBattery_voltage())
                .set("battery_value",heartData.getBattery_value())
                .set("IMSI",heartData.getIMSI())
                .set("IMEI",heartData.getIMEI())
                .set("ICCID",heartData.getICCID());

        mongoTemplate.upsert(query,update, HeartData.class);
    }

    private HeartData findHeartDataByDeviceIdAndTime(String deviceId, long time){
        Query query = new Query(Criteria.where("deviceId").is(deviceId).and("timestamp").is(time));
        return mongoTemplate.findOne(query,HeartData.class);
    }

    //导入校验（如果有timestamp和deviceId重合则更新）
    public void saveHeartDatas(List<HeartData> list){
        for (HeartData heartData:
                list) {
            HeartData po = findHeartDataByDeviceIdAndTime(heartData.getDeviceId(),heartData.getTimestamp());
            if(po==null){
                mongoTemplate.save(heartData);
            }else{
                updateHeartData(heartData);
            }
        }
    }

    public void saveHeartData(HeartData heartData){
        HeartData po = findHeartDataByDeviceIdAndTime(heartData.getDeviceId(),heartData.getTimestamp());
        if(po==null){
            mongoTemplate.save(heartData);
        }else{
            updateHeartData(heartData);
        }
    }

    public HeartData getNewestHeartBeat(String device_id){
        Query query = new Query(Criteria.where("deviceId").is(device_id));
        query.with(new Sort(Sort.Direction.DESC,"timestamp"));
        return mongoTemplate.findOne(query, HeartData.class);
    }

    public HeartData getEarliestHeartBeat(String device_id){
        Query query = new Query(Criteria.where("deviceId").is(device_id));
        query.with(new Sort(Sort.Direction.ASC,"timestamp"));
        return mongoTemplate.findOne(query, HeartData.class);
    }

    public Integer getHeartBeatTotalNum(String device_id){
        Aggregation aggregation=Aggregation.newAggregation(
                Aggregation.match(Criteria.where("deviceId").is(device_id)),
                Aggregation.group().count().as("count"));
        Integer de = 0;
        try {
            de = (Integer) Objects.requireNonNull(mongoTemplate.aggregate(aggregation, "th_heart_log", Map.class).getUniqueMappedResult()).get("count");
        }catch (NullPointerException e){
            return 0;
        }
        return de;

    }

    public List<HeartData> getHeartBeatList(String device_id,long start_time,long end_time){
        Query query = new Query(Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("timestamp").gt(start_time),Criteria.where("timestamp").lt(end_time)));
        query.with(new Sort(Sort.Direction.ASC,"timestamp"));

        return mongoTemplate.find(query, HeartData.class);
    }

    public List<HeartData> getHeartBeatDataAtTime(String device_id,long start_time,long end_time){
        Query query = new Query(Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("timestamp").gt(start_time),Criteria.where("timestamp").lt(end_time)));
        query.with(new Sort(Sort.Direction.DESC,"timestamp"));

        return mongoTemplate.find(query, HeartData.class);
    }

    public StaticBean getBatteryVoltageStatic(String device_id,long start_time,long end_time){
        Aggregation aggregation=Aggregation.newAggregation(
                Aggregation.match(Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("timestamp").gt(start_time),Criteria.where("timestamp").lt(end_time))),
                Aggregation.group().max("battery_voltage").as("max").min("battery_voltage").as("min").avg("battery_voltage").as("avg"));

        StaticBean staticBean =  mongoTemplate.aggregate(aggregation,"th_heart_log", StaticBean.class).getUniqueMappedResult();
        //平均值保留两位小数
        if(staticBean==null){
            staticBean = new StaticBean().setAvg("").setMax("").setMin("");
            return staticBean;
        }else{
            String avg = DataUtils.getDoubleString(staticBean.getAvg());
            String min = DataUtils.getDoubleString(staticBean.getMin());
            String max = DataUtils.getDoubleString(staticBean.getMax());
            staticBean.setAvg(avg);
            staticBean.setMax(max);
            staticBean.setMin(min);
            return staticBean;
        }


    }


    private StaticBean getMyStatic(Aggregation aggregation){
        StaticBean staticBean =  mongoTemplate.aggregate(aggregation,"th_heart_log", StaticBean.class).getUniqueMappedResult();
        //平均值保留两位小数
        if(staticBean==null){
            staticBean = new StaticBean().setAvg("").setMax("").setMin("");
            return staticBean;
        }else{
            String avg = DataUtils.getDoubleString(staticBean.getAvg());
            staticBean.setAvg(avg);
            return staticBean;
        }
    }

    public StaticBean getRsrpStatic(String device_id,long start_time,long end_time){
        Aggregation aggregation=Aggregation.newAggregation(
                Aggregation.match(Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("timestamp").gt(start_time),Criteria.where("timestamp").lt(end_time))),
                Aggregation.group().max("rsrp").as("max").min("rsrp").as("min").avg("rsrp").as("avg"));

        return getMyStatic(aggregation);
    }

    public StaticBean getEclStatic(String device_id,long start_time,long end_time){
        Aggregation aggregation=Aggregation.newAggregation(
                Aggregation.match(Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("timestamp").gt(start_time),Criteria.where("timestamp").lt(end_time))),
                Aggregation.group().max("ecl").as("max").min("ecl").as("min").avg("ecl").as("avg"));

        return getMyStatic(aggregation);
    }

    public StaticBean getSinrStatic(String device_id,long start_time,long end_time){
        Aggregation aggregation=Aggregation.newAggregation(
                Aggregation.match(Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("timestamp").gt(start_time),Criteria.where("timestamp").lt(end_time))),
                Aggregation.group().max("sinr").as("max").min("sinr").as("min").avg("sinr").as("avg"));

        return getMyStatic(aggregation);
    }

}
